/*
 *
 *  Copyright (C) 2008-2010 GSyC/LibreSoft, Universidad Rey Juan Carlos
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *
 *  Author : Roberto Calvo Palomino <rocapal@gsyc.es>
 *
 */

package com.LibreGeoSocial.App;


import java.io.File;
import java.util.List;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.LibreGeoSocial.Api.LibreGeoSocial;
import com.LibreGeoSocial.Api.User;
import com.LibreGeoSocial.Api.Layers.LibreGeoSocialLayer;
import com.LibreGeoSocial.App.AlarmManager.AlarmService;
import com.LibreGeoSocial.App.OMF.OMFManager;
import com.LibreGeoSocial.App.Overlay.PositionOverlay;
import com.LibreGeoSocial.App.Routes.ILocationServiceListener;
import com.LibreGeoSocial.App.Routes.LocationService;
import com.LibreGeoSocial.App.Routes.RouteMap;
import com.LibreGeoSocial.App.Routes.RoutePreferences;
import com.LibreGeoSocial.App.Utils.TinyUrl;
import com.LibreGeoSocial.App.R;
import com.LibreGeoSocial.App.LibreGeoSocialApp;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.winterwell.jtwitter.Twitter;
import com.winterwell.jtwitter.TwitterException;

public class Home extends MapActivity implements Runnable, OnClickListener  {
	
    private ProgressDialog pd;
    
	LocationManager mLocationManager;
	Location mLocation;
	MyLocationListener mLocationListener;
	Button btLogOut;
	
	public static Location currentLocation = null;
	
	TextView outlat;
	TextView outlong;
	MapView mapView = null;
	ImageView imageUser;
	TextView txtUserName;
	TextView txtState;
	
	private static final int MENU_RESOURCES = Menu.FIRST + 1;
	private static final int MENU_STATE = Menu.FIRST + 2;
	private static final int MENU_TRACES = Menu.FIRST + 3;
	private static final int MENU_GROUPS = Menu.FIRST + 4;
	private static final int MENU_LOCATION = Menu.FIRST + 5;
	private static final int MENU_LOCATION_UPDATE = Menu.FIRST + 6;
	private static final int MENU_LOCATION_PUBLISH = Menu.FIRST + 7;
	private static final int MENU_LOCATION_CONFIG = Menu.FIRST + 8;
	private static final int MENU_LOCATION_OTHERS = Menu.FIRST + 9;	
	private static final int MENU_SETTINGS = Menu.FIRST + 10;
	private static final int MENU_AUGMENTED_REALITY = Menu.FIRST + 11;
	private static final int MENU_ABOUT = Menu.FIRST + 12;
	private static final int MENU_AR= Menu.FIRST + 13;

	
	private static final int DIALOG_UPDATE_STATE = 1;
	private static final int DIALOG_ABOUT = 2;
	
	private static final int REQUEST_PREFERENCES = 1;
	
	// The state of gps is saved in this variable
	private static boolean gpsState;
	
	private String LocationType;
	
	private GeoPoint geoPoint;
	
	private User user;
	
	private PositionOverlay myposOverlay = null;

		
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
 
        setContentView(R.layout.home);
        btLogOut = (Button)this.findViewById(R.id.btLogout);
        btLogOut.setOnClickListener(this);
        LocationType = LocationManager.GPS_PROVIDER;
        
        imageUser = (ImageView)this.findViewById(R.id.imgUser);

        txtUserName = (TextView) this.findViewById(R.id.lbName);
        txtState = (TextView) this.findViewById(R.id.lbState);
        
        //writeSignalGPS();
                
        user = LibreGeoSocial.getInstance().getInfoUser(true, null); 
        
        if (user == null)
        	Log.e("HOME: ", "user==null");
        
        if (user.getAvatarId()==null)
        	imageUser.setImageResource(R.drawable.user_70);
        else
        	imageUser.setImageBitmap(user.getAvatarBitmap());
        		
        			
        // Save the last known location
        LocationService.setLastKnownLocation(user.getLocation());
        currentLocation = user.getLocation();
        showMap();
        
        txtUserName.setText (user.getName());
        txtState.setText(user.getState());
                      
        
        /* Start location service */
		startService(new Intent(this,LocationService.class));		
		
		LocationService.registerLocationListener ( new ILocationServiceListener () {
			
			public void updateCurrentLocation(Location loc) {
			                
                setCurrentLocation(loc);
                showMap();

			}

		});
		
		/* Start Alarm Service */
		startService (new Intent (this, AlarmService.class));
        
		refreshOMFdata();
    }
    
	protected void onResume(){
		super.onResume();
		
		
		
		setCurrentLocation(LocationService.getCurrentLocation());
		showMap();
	}
	
	
    @Override
    public void onDestroy() 
	{
    	SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
		
		// location service status
		boolean active = sharedPreferences.getBoolean (RoutePreferences.KEY_LOCATION_SERVICE, false);
		
		if (!active)
		{		
	    	// Stop Location Service
	    	stopService(new Intent(this,LocationService.class));	
	    	stopService(new Intent(this,AlarmService.class));
		}
		
		//del temporal files
		deleteFiles();
    	
    	super.onDestroy();
	}
	
    private void deleteFiles() {
    	
    	
		String tmp_path = getResources().getString(R.string.tmp_path);
        File dir = new File(tmp_path);

        String[] children = dir.list();
        if (children != null) {
                for (int i=0; i<children.length; i++) {
                        String filename = children[i];
                        File f = new File(tmp_path + filename);
                        if (f.exists()) {
                                f.delete();
                        }
                }
        }
    }
    
    private void refreshOMFdata(){
    	SharedPreferences sharedPreferences = 
	    	PreferenceManager.getDefaultSharedPreferences(getBaseContext());
	    
    	OMFManager.setPhone(sharedPreferences.getString(
    			LGS_Preferences.KEY_MOVISTAR_USER, ""));
    	OMFManager.setMovPwd(sharedPreferences.getString(
    			LGS_Preferences.KEY_MOVISTAR_PASSWORD, ""));
//    	OMFManager.setMovLocalizamePwd(sharedPreferences.getString(
//    			LGS_Preferences.KEY_MOVISTAR_LOCALIZAME_PWD, ""));
    }
    
    private void setCurrentLocation(Location loc) {
    	currentLocation = loc;	
    	LibreGeoSocial.getInstance().setUserPosition(loc.getLatitude(), 
    												 loc.getLongitude(),
    												 loc.getAltitude());
    	user.setLatitude(loc.getLatitude());
    	user.setLongitude(loc.getLongitude());
    }
    
	public void onClick(View arg0) {
		if (btLogOut.isPressed())
		{
			Intent i = new Intent(this,LibreGeoSocialApp.class);
	        startActivity(i);
	        this.finish();
		}
		else if ( LocationService.getLocProvider()==LocationManager.GPS_PROVIDER && getGPSStatus()==false)
		{
			Intent settingsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
			settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
			this.startActivityForResult(settingsIntent, 0);
		}
		else
			writeSignalGPS();
		
	}
	
	
	private boolean getGPSStatus()
	{
	    String allowedLocationProviders =
	        Settings.System.getString(getContentResolver(),
	        Settings.System.LOCATION_PROVIDERS_ALLOWED);
	 
	    if (allowedLocationProviders == null) {
	        allowedLocationProviders = "";
	    }
	 
	    return allowedLocationProviders.contains(LocationManager.GPS_PROVIDER);
	}   
	 
    
    private void writeSignalGPS() {
    	
		Toast.makeText(getBaseContext(), 
				   "Trying to get your location ...",
				   Toast.LENGTH_LONG).show();
		
		Location auxLocation = LocationService.getLastKnowLocation();
		
		if (auxLocation!=null)
		{
			setCurrentLocation(auxLocation);
			showMap();
		}
		
    	/*
    	DialogInterface.OnCancelListener dialogCancel = new DialogInterface.OnCancelListener() {

            public void onCancel(DialogInterface dialog) 
            {

            	mLocationManager.removeUpdates(mLocationListener);
            }
          
        };
    	
		pd = ProgressDialog.show(this, this.getResources().getString(R.string.search), 
				this.getResources().getString(R.string.search_signal_gps), true, true, dialogCancel);
		
		Thread thread = new Thread(this);
		thread.start();
		*/

    }
    
    private void showMap()
    {
    	
    	if (mapView == null)
    		mapView = (MapView) findViewById(R.id.myMapView);
    	 
		
    	mapView.setBuiltInZoomControls(true); 
    	
        MapController mapControl = mapView.getController();
        
        geoPoint = new GeoPoint(  (int) (currentLocation.getLatitude() * 1000000), 
        						  (int) (currentLocation.getLongitude() * 1000000));
        mapControl.setZoom(17);
        mapControl.animateTo(geoPoint);
        
        if (myposOverlay == null)
        	myposOverlay = new PositionOverlay();        
        else
        	mapView.removeAllViews();
        
        myposOverlay.setUser(user);
        
	    final List<Overlay> overlays = mapView.getOverlays();	 
	    overlays.clear();
	    overlays.add( myposOverlay );
    	
	    mapView.setClickable(true);
        
    }
    
    @Override
    protected Dialog onCreateDialog(int id) {
        
    	switch (id) {
    	
	    	case DIALOG_ABOUT:
	    		
	    		LayoutInflater factory1 = LayoutInflater.from(this);
	    		final View textEntryView1 = factory1.inflate(R.layout.custom_dialog, null);
	    		
	    		TextView text = (TextView) textEntryView1.findViewById (R.id.dialog_text);
	    		ImageView image = (ImageView) textEntryView1.findViewById(R.id.dialog_image);
	
	    		text.setText("LibreGeoSocial " + getString(R.string.version_lgs) +
	    					getString(R.string.revision_lgs) + "\n" +
	    				     "Copyright (C) GSyC/LibreSoft \n\n" +
	    				     "This software is under GPL v3.0 license!\n\n"+	    				     
	    				     "Authors: \n"+
	    				     "  The developers of LibreGeoSocial.\n\n" +
	    				     "Web: http://www.libregeosocial.org" );
	
	    		
		        return new AlertDialog.Builder(this)	        
		        .setTitle("About")		        
		        .setView(textEntryView1) 
		        .setIcon(R.drawable.logo)
		        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		            	
		            }
		        })
		        .setNegativeButton("Go web!", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		            	
		    			Intent myIntent = new Intent(Intent.ACTION_VIEW, 
			 					 Uri.parse("http://www.libregeosocial.org/"));
		    			startActivity(myIntent);
		            }
		        })
			    .create();
	        
	    	case DIALOG_UPDATE_STATE:
	    		
	    		LayoutInflater factory = LayoutInflater.from(this);
	    		final View textEntryView = factory.inflate(R.layout.state, null);
	    		
	    		final EditText edit = (EditText) textEntryView.findViewById (R.id.txtstate);
	    		edit.setText("");
	    		
		        return new AlertDialog.Builder(this)	        
		        .setTitle("Update state")
		        .setView(textEntryView)
		        .setPositiveButton("update", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		
		            	if ( LibreGeoSocial.getInstance().setStatus(edit.getText().toString()))
		            	{		            		
		            		txtState.setText(edit.getText().toString());
		            		
		                    // User text    
		            	    SharedPreferences sharedPreferences = 
		            	    	PreferenceManager.getDefaultSharedPreferences(getBaseContext());

		            		// Update state in twitter
		            		Boolean syncTwitter = 
		            			sharedPreferences.getBoolean(LGS_Preferences.KEY_TWITTER_ACTIVE, false);
		            		if (syncTwitter)
		            		{
		            	        
		            	        Twitter twitter = new Twitter(
		            	        		sharedPreferences.getString(LGS_Preferences.KEY_TWITTER_USER, ""),
		            	        		sharedPreferences.getString(LGS_Preferences.KEY_TWITTER_PASSWORD, ""));
		            	        try {
		            	        	twitter.updateStatus(edit.getText().toString());
		            			} catch (TwitterException e) {		            				
		            				Log.e("Home",e.getMessage());
		            			}
		            		}
		            	}
		            	else
		            	{
		            		Toast.makeText(getBaseContext(), 
			     					   "Error while the status was setted: " + 
			     					   LibreGeoSocial.getInstance().getLastMsgServer(), 
			     					   Toast.LENGTH_LONG).show();
		            	}
		            	
		                /* User clicked OK so do some stuff */
		            }
		        })
		        .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		
		                /* User clicked cancel so do some stuff */
		            }
		        })
		        .create();
		    
    	}
    	
    	return null;
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	

        
        /*menu.add(0, MENU_TRACES, 0 ,"Routes")
		.setIcon(R.drawable.ruta_negro_48)
        .setAlphabeticShortcut('C');
       */
        /*
        menu.add(0, MENU_GROUPS, 0 ,"Groups")
		.setIcon(R.drawable.group)
        .setAlphabeticShortcut('G');
        */
        
        /*
        menu.add(0, MENU_AUGMENTED_REALITY, 0 ,"Augmented reality")
		.setIcon(R.drawable.real_view)
        .setAlphabeticShortcut('A');
        */
    	
    	
        
        SubMenu sub = menu.addSubMenu (0, MENU_LOCATION, 0 , "Location")
        			  .setIcon(R.drawable.mundo);
        
        
        //sub.add(0,MENU_LOCATION_GPS,0, "GPS");
        //sub.add(0,MENU_LOCATION_WIFI,0, "WIFI");
        
        sub.add(0,MENU_LOCATION_UPDATE,0,"Update");
        sub.add(0,MENU_LOCATION_PUBLISH,0,"Publish");
        sub.add(0,MENU_LOCATION_CONFIG,0,"Config");
        sub.add(0,MENU_LOCATION_OTHERS,0,"Others");
        
        super.onCreateOptionsMenu(menu);
        
        menu.add(0, MENU_AR, 0, "Augmented Reality")
		.setIcon(R.drawable.real_view)
        .setAlphabeticShortcut('A');
        
        menu.add(0, MENU_STATE, 0 , "Status")
        		.setIcon(R.drawable.refresh_48)
                .setAlphabeticShortcut('U');

        menu.add(0, MENU_SETTINGS, 0 ,"Settings")
			.setIcon(R.drawable.spanner_48)
	        .setAlphabeticShortcut('S');
        
        menu.add(0, MENU_ABOUT, 0, "About")
	    .setIcon(R.drawable.icon)
        .setAlphabeticShortcut('B');   
        
        return true;
    }

    @Override
    public boolean onOptionsItemSelected (MenuItem item) {
    	
    	switch (item.getItemId()) {
    	
    	case MENU_AUGMENTED_REALITY:
        	
    		Intent i = new Intent(this,LayerList.class); 
        	startActivity(i); 
        	
    		break;

    	case MENU_ABOUT:
    		
    		showDialog(DIALOG_ABOUT);
    		break;
    		
    	case MENU_STATE:
    		
			showDialog(DIALOG_UPDATE_STATE);
    		
    		break;
    		
    	case MENU_TRACES:
    		Intent i2 = new Intent(this,RouteMap.class);
        	startActivity(i2); 

        	break;
        	
    	case MENU_GROUPS:
    		Intent i4 = new Intent(this,GroupList.class);
        	startActivity(i4); 

        	break;
    		
    	case MENU_LOCATION_OTHERS:
    		
    		Intent i1 = new Intent(this,LocationWays.class);
        	startActivity(i1);
    		
    		break;
    		
    	case MENU_SETTINGS:
    	case MENU_LOCATION_CONFIG:
    		
    		Intent i3 = new Intent(this,LGS_Preferences.class);
        	startActivityForResult(i3, REQUEST_PREFERENCES);
    		
    		break;
    		
    	case MENU_LOCATION_UPDATE:
    		writeSignalGPS();
    		break;
    	
    	case MENU_LOCATION_PUBLISH:
    		
    		String urlLoc = "http://maps.google.com/maps?f=q&source=s_q&hl=es&geocode=&q=" + 
    		              String.valueOf(currentLocation.getLatitude()) + "," + 
    		              String.valueOf(currentLocation.getLongitude()) + "&ie=UTF8&z=17";
    			
    		String text = "My current location: " + TinyUrl.getTinyUrl(urlLoc) + " - @LibreGeoSocial ";
    		
            Intent i5 = new Intent(Intent.ACTION_SEND);
            i5.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            i5.setType("text/plain");
            i5.putExtra(Intent.EXTRA_TEXT, text);
            startActivity(i5);
    		
    		break;
    		
    	case MENU_AR:
    		
    		Intent IntentLGS = new Intent(this, new NodeList().getClass() );
    		LibreGeoSocialLayer layer1 = new LibreGeoSocialLayer("lgs",5.0,"");
    		IntentLGS.putExtra ("layer",layer1);
    		
    		startActivity(IntentLGS);
    		
        }
        return super.onOptionsItemSelected(item);
    }
    
	protected void onActivityResult (int requestCode, int resultCode, Intent data) {	 
		
		switch (requestCode) { 
		
	    	case REQUEST_PREFERENCES:
	    				
	    		// Stop Location Service
	        	stopService(new Intent(this,LocationService.class));
	    		
	    		/* Start location service */
	    		startService(new Intent(this,LocationService.class));	
	    		
	    		break;
		}
	}	
    
	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	} 
	
	public void run() {
    	
		mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		
		if (mLocationManager.isProviderEnabled(LocationService.getLocProvider())) {
			
			Looper.prepare();
			
			mLocationListener = new MyLocationListener();
			
			mLocationManager.requestLocationUpdates(
					LocationType, 0, 0, mLocationListener);
			
			Looper.loop(); 
			Looper.myLooper().quit(); 
			
		} else {
			
			
            Toast.makeText(getBaseContext(), 
                    getString(R.string.gps_signal_not_found), 
                    Toast.LENGTH_LONG).show();
            
		}
	}
	
	
    
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			
			pd.dismiss();
			
			mLocationManager.removeUpdates(mLocationListener);
	    	if (currentLocation!=null) {
	    		showMap();	    		
	    	}
		}
	};
	
	
    private class MyLocationListener implements LocationListener 
    {

        public void onLocationChanged(Location loc) {
            if (loc != null) {
                Toast.makeText(getBaseContext(), 
                    getResources().getString(R.string.gps_signal_found), 
                    Toast.LENGTH_LONG).show();
                setCurrentLocation(loc);
                handler.sendEmptyMessage(0);
            }
        }


        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub
        }


        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub
        }


        public void onStatusChanged(String provider, int status, 
            Bundle extras) {
            // TODO Auto-generated method stub
        }
    }



    
}

